//
//  WordDetialViewController.m
//  JPWords
//
//  Created by 梁淑婷 on 2024/7/5.
//

#import "WordDetialViewController.h"
#import <AVFoundation/AVFoundation.h>
#import "WordErrorViewController.h"
#import "CollectSaveManager.h"
#import "WordCollectDeleteManager.h"
#import "nuisdk/NeoNuiTts.h"
#import "AudioController.h"
#import <AdSupport/ASIdentifierManager.h>
#import "GetALiYunTokenManager.h"
#import "NeoNuiTtsManager.h"

@interface WordDetialViewController ()<
///AVSpeechSynthesizerDelegate,
JPAPIManagerCallBackDelegate,
NeoNuiTtsDelegate
>

@property(nonatomic,strong)UIButton *topErrorBtn;
@property(nonatomic,strong)UIButton *collectBtn;
@property(nonatomic,strong)UILabel *pronunciationLabel;//发音
@property(nonatomic,strong)UILabel *writeLabel;//书写
@property(nonatomic,strong)UILabel *toneLabel;//音调
@property(nonatomic,strong)UILabel *wordTipLabel;
@property(nonatomic,strong)UILabel *wordLabel;
@property(nonatomic,strong)UILabel *exampleTipLabel;
@property(nonatomic,strong)UILabel *exampleLabel;
@property(nonatomic,strong)UILabel *exampleTranslateLabel;
//@property(nonatomic,strong)AVSpeechSynthesizer *synthesizer;
@property(nonatomic,strong)CollectSaveManager *collectSaveManager;
@property(nonatomic,strong)WordCollectDeleteManager *collectDeleteManager;
@property(nonatomic,strong)NeoNuiTts *nui;
@property(nonatomic,strong)AudioController *audioController;
@property (nonatomic, strong) dispatch_queue_t work_queue;
@property(nonatomic,strong)GetALiYunTokenManager *aLiYunTokenManager;
@property(nonatomic,strong)UIImageView *topImageView;
@property(nonatomic,strong)UIView *cardView;
@property(nonatomic,strong)AVPlayer *avPlayer;
@property(nonatomic,assign)BOOL isPlaying;

@end

@implementation WordDetialViewController

-(CollectSaveManager *)collectSaveManager{
    if(!_collectSaveManager){
        _collectSaveManager = [[CollectSaveManager alloc]init];
        _collectSaveManager.delegate = self;
    }
    return _collectSaveManager;
}

-(WordCollectDeleteManager *)collectDeleteManager{
    if(!_collectDeleteManager){
        _collectDeleteManager = [[WordCollectDeleteManager alloc]init];
        _collectDeleteManager.delegate = self;
    }
    return _collectDeleteManager;
}

-(GetALiYunTokenManager *)aLiYunTokenManager{
    if(!_aLiYunTokenManager){
        _aLiYunTokenManager = [[GetALiYunTokenManager alloc]init];
        _aLiYunTokenManager.delegate = self;
    }
    return _aLiYunTokenManager;
}


-(void)viewDidLoad{
    [super viewDidLoad];
    
    [self initPlay];
    [self NuiTtsInit];
    
    [self createUI];
    
    //听力播放结束
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(playToEndTime:) name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
    
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    // 重新设置 delegate 确保回调正常工作
    if (self.nui){
        self.nui.delegate = self;
    }
}

-(void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    
    if(self.work_queue){
        dispatch_async(self.work_queue, ^{
            // 如果上个任务没有合成完毕，手动取消
            if(self.nui){
                [self.nui nui_tts_cancel:NULL];
            }
        });
    }
    if(self.audioController){
        [self.audioController cleanPlayerBuffer];
    }
    
    if(self.avPlayer&&self.isPlaying == YES){
        [self.avPlayer pause];
        self.isPlaying = NO;
    }
    
}

#pragma mark - 语音合成播放需要
-(void)initPlay{
    
    self.audioController = [[AudioController alloc] init:only_player];
    [self.audioController setPlayerSampleRate:16000];// 16000返回音频的采样率
    
    self.work_queue = dispatch_queue_create("WordDetialViewController_WorkQueue", DISPATCH_QUEUE_CONCURRENT);
    
}

#pragma mark - 语音合成初始化
-(void)NuiTtsInit{
    if (self.nui == NULL||self.nui == nil) {
        self.nui = [NeoNuiTtsManager sharedManager].nui;
        self.nui.delegate = self;
    }
    //请注意此处的参数配置，其中账号相关需要按照genInitParams的说明填入后才可访问服务
    NSString * initParam = [self genInitParams];
    int retcode = [self.nui nui_tts_initialize:[initParam UTF8String] logLevel:LOG_LEVEL_VERBOSE saveLog:YES];
    
    NSString *fontName = @"tomoka";
    [self.nui nui_tts_set_param:"font_name" value:[fontName UTF8String]];
    //在线合成
    [self.nui nui_tts_set_param:"mode_type" value:"2"]; // 必填
    NSString *speed_level = @"1";
    [self.nui nui_tts_set_param:"speed_level" value:[speed_level UTF8String]];
    NSString *pitch_level = @"0";
    [self.nui nui_tts_set_param:"pitch_level" value:[pitch_level UTF8String]];
    NSString *volume = @"2";
    [self.nui nui_tts_set_param:"volume)" value:[volume UTF8String]];
    // 字级别音素边界功能开关，该参数只对支持字级别音素边界接口的发音人有效。“1”表示打开，“0”表示关闭。
    [self.nui nui_tts_set_param:"enable_subtitle" value:"1"];
    
    if (retcode != 0) {
         TLog(@"init failed.retcode:%d", retcode);
         return;
    }
    
}

-(NSString *)genInitParams{
    NSString *strResourcesBundle = [[NSBundle mainBundle] pathForResource:@"Resources" ofType:@"bundle"];
    NSString *bundlePath = [[NSBundle bundleWithPath:strResourcesBundle] resourcePath];
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsPath = [paths objectAtIndex:0];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSString *testDirectory = [documentsPath stringByAppendingPathComponent:@"voices"];
    // 创建目录
    BOOL res=[fileManager createDirectoryAtPath:testDirectory withIntermediateDirectories:YES attributes:nil error:nil];
    if (res) {
        TLog(@"文件夹创建成功");
    }else{
        TLog(@"文件夹创建失败");
    }
    NSString *debug_path = testDirectory;
    NSMutableDictionary *ticketJsonDict = [NSMutableDictionary dictionary];
    [ticketJsonDict setObject:ALIYUNYUYINKEY forKey:@"app_key"];
    [self checkToken];
    NSString *TOKEN = [[NSUserDefaults standardUserDefaults]objectForKey:@"ALIYUN_YUYIN_TOKEN"];
    if(!TOKEN){
        TOKEN = @"";
    }
    [ticketJsonDict setObject:TOKEN forKey:@"token"];
    
    //工作目录路径，SDK从该路径读取配置文件
    [ticketJsonDict setObject:bundlePath forKey:@"workspace"]; // 必填, 且需要有读写权限
//    TLog(@"workspace:%@", bundlePath);
    [ticketJsonDict setObject:debug_path forKey:@"debug_path"];
//    TLog(@"debug_path:%@", debug_path);

    [ticketJsonDict setObject:@"wss://nls-gateway.aliyuncs.com/ws/v1" forKey:@"url"]; // 默认

    // 设置成在线语音合成模式, 这个设置很重要, 遗漏会导致无法运行
    [ticketJsonDict setObject:@"2" forKey:@"mode_type"]; // 必填
    
    NSString *id_string = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
//    TLog(@"id: %s", [id_string UTF8String]);
    [ticketJsonDict setObject:id_string forKey:@"device_id"]; // 必填, 推荐填入具有唯一性的id, 方便定位问题

    NSData *data = [NSJSONSerialization dataWithJSONObject:ticketJsonDict options:NSJSONWritingPrettyPrinted error:nil];
    NSString * jsonStr = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
    return jsonStr;
}

#pragma mark - 获取token
-(void)checkToken{
    NSString *token = [[NSUserDefaults standardUserDefaults]objectForKey:@"ALIYUN_YUYIN_TOKEN"];
    if(token){
        //token 存在 判断时间
        NSString *expireTime = [[NSUserDefaults standardUserDefaults]objectForKey:@"ALIYUN_YUYIN_EXPIRETIME"];
        if(expireTime){
            NSDate *currentDate = [NSDate date];
            NSTimeInterval expireTimeInterval = [expireTime doubleValue];
            NSDate *expireDate = [NSDate dateWithTimeIntervalSince1970:expireTimeInterval];
            if ([currentDate compare:expireDate] != NSOrderedAscending) {
                // 当前时间等于或在过期时间之后 已经到了过期时间
                [self.aLiYunTokenManager loadData];

            } else {
                // 当前时间在过期时间之前 还没到过期时间
            }
        }else{
            [self.aLiYunTokenManager loadData];
        }
    }else{
        [self.aLiYunTokenManager loadData];
    }
}


-(void)createUI{
    
    self.customNavigationBar.backgroundColor = [UIColor clearColor];
    self.view.backgroundColor = [UIColor whiteColor];
    
    CGFloat h636 = [DeviceUtils getAdaptedWidthForDesignWidth:636 andCurrentAvailableWidth:self.currentAvailableWidth];
    if(h636 > self.currentAvailableHeight){
        h636 = self.currentAvailableHeight;
    }
    UIImageView *topImageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, self.currentAvailableWidth,h636)];
    topImageView.userInteractionEnabled = YES;
    topImageView.image = [UIImage imageNamed:@"memorize_words_top_bg"];
    [self.view addSubview:topImageView];
    self.topImageView = topImageView;
    
    UIButton *closeBtn = [[UIButton alloc]init];
    [closeBtn setImage:[UIImage imageNamed:@"nav_close"] forState:UIControlStateNormal];
    [closeBtn addTarget:self action:@selector(closeBtnClick) forControlEvents:UIControlEventTouchUpInside];
    [self.customNavigationBar addSubview:closeBtn];
    [closeBtn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.width.height.mas_equalTo(@44);
        make.left.mas_equalTo(@6);
        make.bottom.mas_equalTo(@2);
    }];
    
    UIView *cardView = [[UIView alloc]initWithFrame:CGRectMake(20, kYM_NAVIGATIONBAR_HEIGHT+16, self.currentAvailableWidth-40,self.currentAvailableHeight-kYM_NAVIGATIONBAR_HEIGHT-16-74)];
    cardView.backgroundColor = kCardBgColor(cardView.width,cardView.height);
    cardView.layer.cornerRadius = 20;
    cardView.layer.shadowColor = UIColorHex_(0x000000,0.06).CGColor;
    cardView.layer.shadowOffset = CGSizeMake(0,2);
    cardView.layer.shadowOpacity = 1;
    cardView.layer.shadowRadius = 20;
    [self.view addSubview:cardView];
    self.cardView = cardView;
    
    self.topErrorBtn = [[UIButton alloc]initWithFrame:CGRectMake(8,6,48,30)];
    [self.topErrorBtn setTitle:@"报错" forState:UIControlStateNormal];
    [self.topErrorBtn setTitleColor:UIColorHex(0xB5CCC7) forState:UIControlStateNormal];
    self.topErrorBtn.titleLabel.font = JPUIFontPingFangSCRegular(14);
    [self.topErrorBtn addTarget:self action:@selector(topErrorBtnClick) forControlEvents:UIControlEventTouchUpInside];
    [cardView addSubview:self.topErrorBtn];
    
    self.collectBtn = [[UIButton alloc]initWithFrame:CGRectMake(cardView.width-46,6,40,40)];
    [self.collectBtn setImage:[UIImage imageNamed:@"word_card_uncollect"] forState:UIControlStateNormal];
    [self.collectBtn setImage:[UIImage imageNamed:@"word_card_collect"] forState:UIControlStateSelected];
    self.collectBtn.ym_acceptEventInterval = 1.0;
    [self.collectBtn addTarget:self action:@selector(collectBtnClick) forControlEvents:UIControlEventTouchUpInside];
    if(self.wordModel.isCollect){
        self.collectBtn.selected = self.wordModel.isCollect.integerValue == 1?YES:NO;
    }else{
        self.collectBtn.selected = NO;
    }
    [cardView addSubview:self.collectBtn];
   
    CGFloat h120 =  [DeviceUtils getAdaptedHeightForDesignHeight:120 andCurrentAvailableHeight:self.currentAvailableHeight];
    self.pronunciationLabel = [[UILabel alloc]initWithFrame:CGRectMake(16,h120,cardView.width-32,34)];
    self.pronunciationLabel.font = JPUIFontNotoSansJPMedium(24);
    self.pronunciationLabel.textColor = KFontBlackColor;
    self.pronunciationLabel.textAlignment = NSTextAlignmentCenter;
    self.pronunciationLabel.text = self.wordModel.pronunciation;
    [cardView addSubview:self.pronunciationLabel];
    
    CGFloat w2 = [self getStringWidthWithText:self.wordModel.writing?self.wordModel.writing:@"" font:JPUIFontNotoSansJPMedium(48) viewHeight:67];
    CGFloat tone_w = [self getStringWidthWithText:self.wordModel.tone font:JPUIFontNotoSansJPMedium(20) viewHeight:28];
    BOOL ismax = NO;
    if(w2 > (cardView.width-34-tone_w*2-20)){
        w2 = cardView.width-34-tone_w*2-20;
        ismax = YES;
    }
    CGFloat left = (cardView.width-w2-2)/2.0;
    self.writeLabel = [[UILabel alloc]initWithFrame:CGRectMake(left,CGRectGetMaxY(self.pronunciationLabel.frame),w2+2,67)];
    self.writeLabel.font = JPUIFontNotoSansJPMedium(48);
    self.writeLabel.textColor = KFontBlackColor;
    self.writeLabel.textAlignment = NSTextAlignmentCenter;
    self.writeLabel.userInteractionEnabled = YES;
    self.writeLabel.text = self.wordModel.writing;
    if(ismax == YES){
        self.writeLabel.adjustsFontSizeToFitWidth = YES;
    }else{
        self.writeLabel.adjustsFontSizeToFitWidth = NO;
    }
    [cardView addSubview:self.writeLabel];
    __weak typeof(self)weakSelf = self;
    UITapGestureRecognizer *writeTap = [[UITapGestureRecognizer alloc]initWithActionBlock:^(id  _Nonnull sender) {
        if(weakSelf.wordModel.audio&&![weakSelf.wordModel.audio isEqualToString:@""]){
            [weakSelf playAudio:weakSelf.wordModel.audio];
        }else{
            if((weakSelf.wordModel.pronunciation)&&(![weakSelf.wordModel.pronunciation isEqualToString:@""])){
                if((weakSelf.wordModel.writing)&&(weakSelf.wordModel.isReadWriting)&&([weakSelf.wordModel.isReadWriting isEqualToString:@"1"]||weakSelf.wordModel.isReadWriting.integerValue == 1)){
                    [weakSelf speakJapaneseText:weakSelf.wordModel.writing];
                }else{
                    [weakSelf speakJapaneseText:weakSelf.wordModel.pronunciation];
                }
            }else{
                if((weakSelf.wordModel.writing)&&(![weakSelf.wordModel.writing isEqualToString:@""])){
                    [weakSelf speakJapaneseText:weakSelf.wordModel.writing];
                }
            }
        }
    }];
    [self.writeLabel addGestureRecognizer:writeTap];
    
    self.toneLabel = [[UILabel alloc]initWithFrame:CGRectMake(CGRectGetMaxX(self.writeLabel.frame)+10, CGRectGetMaxY(self.writeLabel.frame)-self.writeLabel.frame.size.height+6,tone_w,28)];
    self.toneLabel.font = JPUIFontNotoSansJPMedium(20);
    self.toneLabel.textColor = KFontBlackColor;
    self.toneLabel.textAlignment = NSTextAlignmentCenter;
    self.toneLabel.text = self.wordModel.tone;
    [cardView addSubview:self.toneLabel];
    
   
    CGFloat h100 =  [DeviceUtils getAdaptedHeightForDesignHeight:100 andCurrentAvailableHeight:self.currentAvailableHeight];
    CGFloat w_tip_w = [self getStringWidthWithText:self.wordModel.speech?self.wordModel.speech:@"" font:JPUIFontPingFangSCRegular(13) viewHeight:22];
    self.wordTipLabel = [[UILabel alloc]initWithFrame:CGRectMake(20,CGRectGetMaxY(self.writeLabel.frame)+h100,w_tip_w+20,22)];
    self.wordTipLabel.font = JPUIFontPingFangSCRegular(13);
    self.wordTipLabel.textColor = KThemeColor;
    self.wordTipLabel.textAlignment = NSTextAlignmentCenter;
    self.wordTipLabel.backgroundColor = UIColorHex(0xE8FAF5);
    self.wordTipLabel.layer.cornerRadius = 11;
    self.wordTipLabel.layer.masksToBounds = YES;
    self.wordTipLabel.text = self.wordModel.speech;
    [cardView addSubview:self.wordTipLabel];
    if(self.wordModel.speech&&(![self.wordModel.speech isEqualToString:@""])){
        self.wordTipLabel.hidden = NO;
    }else{
        self.wordTipLabel.hidden = YES;
    }

    CGFloat h10 =  [DeviceUtils getAdaptedHeightForDesignHeight:10 andCurrentAvailableHeight:self.currentAvailableHeight];
    self.wordLabel = [[UILabel alloc]initWithFrame:CGRectMake(30,CGRectGetMaxY(self.wordTipLabel.frame)+h10,cardView.width-30-20,20)];
    self.wordLabel.numberOfLines = 0;
    self.wordLabel.font = JPUIFontPingFangSCRegular(14);
    self.wordLabel.textColor = KFontGrayColor;
    self.wordLabel.text = self.wordModel.meaning;
    [cardView addSubview:self.wordLabel];
    CGSize w_size = [self.wordLabel sizeThatFits:CGSizeMake(cardView.width-30-20,MAXFLOAT)];
    self.wordLabel.frame = CGRectMake(30,CGRectGetMaxY(self.wordTipLabel.frame)+h10,cardView.width-30-20,ceilf(w_size.height));
    
    
    CGFloat h25 =  [DeviceUtils getAdaptedHeightForDesignHeight:25 andCurrentAvailableHeight:self.currentAvailableHeight];
    self.exampleTipLabel = [[UILabel alloc]initWithFrame:CGRectMake(20,CGRectGetMaxY(self.wordLabel.frame)+h25,46,22)];
    self.exampleTipLabel.font = JPUIFontPingFangSCRegular(13);
    self.exampleTipLabel.textColor = KThemeColor;
    self.exampleTipLabel.text = @"例句";
    self.exampleTipLabel.textAlignment = NSTextAlignmentCenter;
    self.exampleTipLabel.backgroundColor = UIColorHex(0xE8FAF5);
    self.exampleTipLabel.layer.cornerRadius = 11;
    self.exampleTipLabel.layer.masksToBounds = YES;
    [cardView addSubview:self.exampleTipLabel];
    
    self.exampleLabel = [[UILabel alloc]initWithFrame:CGRectMake(30,CGRectGetMaxY(self.exampleTipLabel.frame)+h10,cardView.width-30-20,0)];
    self.exampleLabel.numberOfLines = 0;
    self.exampleLabel.userInteractionEnabled = YES;
    self.exampleLabel.font = JPUIFontNotoSansJPRegular(14);
    self.exampleLabel.text = self.wordModel.example;
    self.exampleLabel.textColor = KFontGrayColor;
    [cardView addSubview:self.exampleLabel];
    CGSize e_size = [self.exampleLabel sizeThatFits:CGSizeMake(cardView.width-30-20,MAXFLOAT)];
    self.exampleLabel.frame = CGRectMake(30,CGRectGetMaxY(self.exampleTipLabel.frame)+h10,cardView.width-30-20,ceilf(e_size.height));
    UITapGestureRecognizer *exampleTap = [[UITapGestureRecognizer alloc]initWithActionBlock:^(id  _Nonnull sender) {
        if(weakSelf.wordModel.example&&weakSelf.wordModel.example.length > 0){
            [weakSelf speakJapaneseText:weakSelf.wordModel.example];
        }
    }];
    [self.exampleLabel addGestureRecognizer:exampleTap];
    
    self.exampleTranslateLabel = [[UILabel alloc]initWithFrame:CGRectMake(30,CGRectGetMaxY(self.exampleLabel.frame)+10,cardView.width-30-20,0)];
    self.exampleTranslateLabel.numberOfLines = 0;
    self.exampleTranslateLabel.userInteractionEnabled = YES;
    self.exampleTranslateLabel.font = JPUIFontPingFangSCRegular(14);
    self.exampleTranslateLabel.text = self.wordModel.exampleMeaning;
    self.exampleTranslateLabel.textColor = KFontGrayColor;
    [cardView addSubview:self.exampleTranslateLabel];
    CGSize e_size2 = [self.exampleTranslateLabel sizeThatFits:CGSizeMake(cardView.width-30-20,MAXFLOAT)];
    self.exampleTranslateLabel.frame = CGRectMake(30,CGRectGetMaxY(self.exampleLabel.frame)+10,cardView.width-30-20,ceilf(e_size2.height));
   
    
}

#pragma mark - 屏幕宽度改变
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];

    if (isIPAD) {
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            // 获取当前可用宽度并更新布局
            self.currentAvailableWidth = [DeviceUtils currentAvailableWidth];
            self.currentAvailableHeight = [DeviceUtils currentAvailableHeight];
            self.customNavigationBar.frame = CGRectMake(0, 0, self.currentAvailableWidth, kYM_NAVIGATIONBAR_HEIGHT);
            CGFloat h636 = [DeviceUtils getAdaptedWidthForDesignWidth:636 andCurrentAvailableWidth:self.currentAvailableWidth];
            if(h636 > self.currentAvailableHeight){
                h636 = self.currentAvailableHeight;
            }
            self.topImageView.frame = CGRectMake(0, 0, self.currentAvailableWidth,h636);
            self.cardView.frame = CGRectMake(20, kYM_NAVIGATIONBAR_HEIGHT+16, self.currentAvailableWidth-40,self.currentAvailableHeight-kYM_NAVIGATIONBAR_HEIGHT-16-74);
            self.collectBtn.frame = CGRectMake(self.cardView.width-46,6,40,40);
            CGFloat h120 =  [DeviceUtils getAdaptedHeightForDesignHeight:120 andCurrentAvailableHeight:self.currentAvailableHeight];
            self.pronunciationLabel.frame = CGRectMake(16,h120,self.cardView.width-32,34);
            CGFloat w2 = [self getStringWidthWithText:self.wordModel.writing?self.wordModel.writing:@"" font:JPUIFontNotoSansJPMedium(48) viewHeight:67];
            CGFloat tone_w = [self getStringWidthWithText:self.wordModel.tone font:JPUIFontNotoSansJPMedium(20) viewHeight:28];
            BOOL ismax = NO;
            if(w2 > (self.cardView.width-34-tone_w*2-20)){
                w2 = self.cardView.width-34-tone_w*2-20;
                ismax = YES;
            }
            CGFloat left = (self.cardView.width-w2-2)/2.0;
            self.writeLabel.frame = CGRectMake(left,CGRectGetMaxY(self.pronunciationLabel.frame),w2+2,67);
            self.toneLabel.frame = CGRectMake(CGRectGetMaxX(self.writeLabel.frame)+10, CGRectGetMaxY(self.writeLabel.frame)-self.writeLabel.frame.size.height+6,tone_w,28);
            CGFloat h100 =  [DeviceUtils getAdaptedHeightForDesignHeight:100 andCurrentAvailableHeight:self.currentAvailableHeight];
            CGFloat w_tip_w = [self getStringWidthWithText:self.wordModel.speech?self.wordModel.speech:@"" font:JPUIFontPingFangSCRegular(13) viewHeight:22];
            self.wordTipLabel.frame = CGRectMake(20,CGRectGetMaxY(self.writeLabel.frame)+h100,w_tip_w+20,22);
            CGFloat h10 =  [DeviceUtils getAdaptedHeightForDesignHeight:10 andCurrentAvailableHeight:self.currentAvailableHeight];
            CGSize w_size = [self.wordLabel sizeThatFits:CGSizeMake(self.cardView.width-30-20,MAXFLOAT)];
            self.wordLabel.frame = CGRectMake(30,CGRectGetMaxY(self.wordTipLabel.frame)+h10,self.cardView.width-30-20,ceilf(w_size.height));
            CGFloat h25 =  [DeviceUtils getAdaptedHeightForDesignHeight:25 andCurrentAvailableHeight:self.currentAvailableHeight];
            self.exampleTipLabel.frame = CGRectMake(20,CGRectGetMaxY(self.wordLabel.frame)+h25,46,22);
            CGSize e_size = [self.exampleLabel sizeThatFits:CGSizeMake(self.cardView.width-30-20,MAXFLOAT)];
            self.exampleLabel.frame = CGRectMake(30,CGRectGetMaxY(self.exampleTipLabel.frame)+h10,self.cardView.width-30-20,ceilf(e_size.height));
            CGSize e_size2 = [self.exampleTranslateLabel sizeThatFits:CGSizeMake(self.cardView.width-30-20,MAXFLOAT)];
            self.exampleTranslateLabel.frame = CGRectMake(30,CGRectGetMaxY(self.exampleLabel.frame)+10,self.cardView.width-30-20,ceilf(e_size2.height));
        });
    }
}


#pragma mark - 返回
-(void)closeBtnClick{
    [self dismissViewControllerAnimated:YES completion:nil];
}

#pragma mark - 报错
-(void)topErrorBtnClick{
    WordErrorViewController *vc = [[WordErrorViewController alloc]init];
    vc.wordModel = self.wordModel;
    [self.navigationController pushViewController:vc animated:YES];
}

#pragma mark - 收藏
-(void)collectBtnClick{
    if(self.collectBtn.selected == NO){
        //收藏
        [self wordCollectWithWordId:self.wordModel.wordId];
    }else{
        //取消收藏
        [self deleteWordCollectWithCollectId:self.wordModel.collectId];
    }
}

#pragma mark - 单词收藏
-(void)wordCollectWithWordId:(NSString*)wordId{
    self.collectSaveManager.wordId = wordId;
    self.collectSaveManager.type = @"1";
    [self.collectSaveManager loadData];
}
#pragma mark - 取消收藏
-(void)deleteWordCollectWithCollectId:(NSString*)collectId{
    self.collectDeleteManager.collectId = collectId;
    [self.collectDeleteManager loadData];
}

#pragma mark - 播放读取文本
- (void)speakJapaneseText:(NSString *)text{
    
    [self listentTypeSet];
    
//    if(!self.synthesizer){
//        self.synthesizer = [[AVSpeechSynthesizer alloc] init];
//        self.synthesizer.delegate = self;
//    }
//    AVSpeechUtterance *utterance = [[AVSpeechUtterance alloc] initWithString:text];
//    utterance.rate = 0.53; // 语速，范围0.0~1.0
//    utterance.pitchMultiplier = 1.1; // 音高，范围0.5~2.0
//    utterance.volume = 1.0; // 音量，范围0~1
//    AVSpeechSynthesisVoice *voice = [AVSpeechSynthesisVoice voiceWithLanguage:@"ja-JP"];
//    utterance.voice = voice;
//    [self.synthesizer speakUtterance:utterance];

    if(self.work_queue){
        dispatch_async(self.work_queue, ^{
            if(self.nui){
                // 如果上个任务没有合成完毕，手动取消，开始合成新的任务
                [self.nui nui_tts_cancel:NULL];
                
                [self UpdateTtsParams:text];
                
                [self.nui nui_tts_play:"1" taskId:"" text:[text UTF8String]];
            }
        });
    }
}

#pragma mark - 更新语音合成参数配置
-(void)UpdateTtsParams:(NSString *)content{
    
    int chars = 0;
    // 支持一次性合成300字符以内的文字，其中1个汉字、1个英文字母或1个标点均算作1个字符，
    // 超过300个字符的内容将会截断。所以请确保传入的text小于300字符(不包含ssml格式)。
    // 长短文本语音合成收费不同，请注意。
    // 300字这个截点可能会变更，以官网文档为准。
    chars = [self.nui nui_tts_get_num_of_chars: [content UTF8String]];
    if (chars > 300) {
        // 超过300字符设置成 长文本语音合成 模式
        [self.nui nui_tts_set_param:"tts_version" value:"1"];
    } else {
        // 未超过300字符设置成 短文本语音合成 模式
        [self.nui nui_tts_set_param:"tts_version" value:"0"];
    }
}

#pragma mark - tts callback
- (void)onNuiTtsEventCallback:(NuiSdkTtsEvent)event taskId:(char*)taskid code:(int)code{
//    TLog(@"onNuiTtsEventCallback event[%d]", event);
    if (event == TTS_EVENT_START) {
//        TLog(@"onNuiTtsEventCallback TTS_EVENT_START");
        // 启动播放器
        [self.audioController startPlayer];
    } else if (event == TTS_EVENT_END || event == TTS_EVENT_CANCEL || event == TTS_EVENT_ERROR) {
        if (event == TTS_EVENT_END) {
//            TLog(@"onNuiTtsEventCallback TTS_EVENT_END");
            // 注意这里的event事件是指语音合成完成，而非播放完成，播放完成需要由audioController对象来进行通知
            [self.audioController drain];
        } else {
            // 取消播报、或者发生异常时终止播放
            if(self.audioController){
                [self.audioController stopPlayer];
            }
        }
        if (event == TTS_EVENT_ERROR) {
            const char *errmsg = [self.nui nui_tts_get_param: "error_msg"];
//            TLog(@"tts get errmsg:%s", errmsg);
            NSString *errorString = [NSString stringWithUTF8String:errmsg];
            if ([errorString containsString:@"144003"]) {
               //token过期
                [self.aLiYunTokenManager loadData];
                dispatch_async(dispatch_get_main_queue(), ^{
                    [JPProgressHUD showWrongMsg:@"语音合成token过期，已重新获取，请再次点击播放"];
                });
            } else {
                dispatch_async(dispatch_get_main_queue(), ^{
                    [JPProgressHUD showWrongMsg:@"语音合成失败"];
                });
            }
        }
      
    }
}

- (void)onNuiTtsUserdataCallback:(char*)info infoLen:(int)info_len buffer:(char*)buffer len:(int)len taskId:(char*)task_id {
    TLog(@"onNuiTtsUserdataCallback info ...");
    if (info_len > 0) {
        TLog(@"onNuiTtsUserdataCallback info text %s. index %d.", info, info_len);
    }
    if (len > 0) {
        [self.audioController write:(char*)buffer Length:(unsigned int)len];
    }
}

-(void)onNuiTtsVolumeCallback:(int)volume taskId:(char*)task_id{
    
}

#pragma mark - 停止当前正在读的文本
- (void)stopSpeaking{
//    if (self.synthesizer&&self.synthesizer.isSpeaking) {
//        [self.synthesizer stopSpeakingAtBoundary:AVSpeechBoundaryImmediate];
//    }
    
    if(self.work_queue){
        dispatch_async(self.work_queue, ^{
            // 如果上个任务没有合成完毕，手动取消
            if(self.nui){
                [self.nui nui_tts_cancel:NULL];
            }
        });
    }
    if(self.audioController){
        [self.audioController stopPlayer];
    }
    
    if(self.avPlayer){
        self.isPlaying = NO;
        [self.avPlayer pause];
        [self.avPlayer seekToTime:kCMTimeZero];
    }
   
}

#pragma mark - 单词音频播放
-(void)playAudio:(NSString *)audio{
    
    [self listentTypeSet];
    
    AVPlayerItem *item = [[AVPlayerItem alloc] initWithURL:[NSURL URLWithString:audio]];
    [item addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
    if(self.avPlayer){
        [self.avPlayer pause];
        [self.avPlayer replaceCurrentItemWithPlayerItem:item];
    }else{
        self.avPlayer = [[AVPlayer alloc] initWithPlayerItem:item];
    }
    [self.avPlayer play];
    self.isPlaying = YES;
}

-(void)playToEndTime:(NSNotification*)notifi{
    [self.avPlayer seekToTime:kCMTimeZero];
    self.isPlaying = NO;
}


-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    if ([keyPath isEqualToString:@"status"]) {
        AVPlayerItemStatus status = [change[NSKeyValueChangeNewKey] integerValue];
        if (status == AVPlayerItemStatusReadyToPlay) {
            NSLog(@"播放成功");
            
        } else if (status == AVPlayerItemStatusFailed) {
            NSLog(@"播放失败");
            [JPProgressHUD showMsg:@"播放失败"];
        }
    }
}

//#pragma mark - AVSpeechSynthesizer deletage
//- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didFinishSpeechUtterance:(AVSpeechUtterance *)utterance{
//    // 当前文本已经读完
//    
//}

#pragma mark - 设置静音模式下也能播放音频
-(void)listentTypeSet{
    // 获取当前的音频会话类别
    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    
    // 检查当前类别是否已经是 AVAudioSessionCategoryPlayback
    if (![audioSession.category isEqualToString:AVAudioSessionCategoryPlayback]) {
        NSError *setCategoryError = nil;
        [audioSession setCategory:AVAudioSessionCategoryPlayback error:&setCategoryError];
        
        if (setCategoryError) {
            NSLog(@"Error setting category: %@", [setCategoryError localizedDescription]);
        }
    }
    
    // 检查音频会话是否已经处于激活状态
    if (!audioSession.isOtherAudioPlaying) {
        NSError *activationError = nil;
        [audioSession setActive:YES error:&activationError];
        
        if (activationError) {
            NSLog(@"Error activating session: %@", [activationError localizedDescription]);
        }
    }
}


#pragma mark - JPAPIManagerCallBackDelegate
-(void)managerCallDLDLAPIDidSuccess:(JPAPIBaseManager *)manager{
   
    if([manager isEqual:self.collectSaveManager]){
        NSDictionary *dic = manager.response.content;
        if(dic[@"message"]){
            [JPProgressHUD showMsg:dic[@"message"]];
        }
        self.wordModel.isCollect = @"1";
        self.wordModel.collectId = [NSString stringWithFormat:@"%@",dic[@"data"][@"collectId"]];
        self.collectBtn.selected = YES;
        [[NSNotificationCenter defaultCenter]postNotificationName:@"WordDetialCollectRefresh" object:self.wordModel];
    }
    
    if([manager isEqual:self.collectDeleteManager]){
        NSDictionary *dic = manager.response.content;
        if(dic[@"message"]){
            [JPProgressHUD showMsg:dic[@"message"]];
        }
        self.wordModel.isCollect = @"0";
        self.wordModel.collectId = @"";
        self.collectBtn.selected = NO;
        [[NSNotificationCenter defaultCenter]postNotificationName:@"WordDetialCollectRefresh" object:self.wordModel];
    }
    
    if([manager isEqual:self.aLiYunTokenManager]){
         NSDictionary *dic = manager.response.content;
         if(dic[@"data"][@"token"]){
             NSString *token = [NSString stringWithFormat:@"%@",dic[@"data"][@"token"]];
             [[NSUserDefaults standardUserDefaults]setObject:token forKey:@"ALIYUN_YUYIN_TOKEN"];
         }
         if(dic[@"data"][@"expireTime"]){
             NSString *expireTime = [NSString stringWithFormat:@"%@",dic[@"data"][@"expireTime"]];
             [[NSUserDefaults standardUserDefaults]setObject:expireTime forKey:@"ALIYUN_YUYIN_EXPIRETIME"];
         }
         if (self.nui) {
           [self.nui nui_tts_release];
           self.nui = nil;
         }
         [self NuiTtsInit];
    }
    
}

-(void)managerCallDLDLAPIDidFailed:(JPAPIBaseManager *)manager{
    if(manager.errorMessage){
        [JPProgressHUD showMsg:manager.errorMessage];
    }
}

-(void)dealloc {
    
    [[NSNotificationCenter defaultCenter]removeObserver:self];
    
    if(self.audioController){
        [self.audioController cleanPlayerBuffer];
    }
    
    if(self.avPlayer&&self.isPlaying == YES){
        [self.avPlayer pause];
        self.isPlaying = NO;
    }
}

@end
